import React from 'react';
import ReactDOM from 'react-dom';

let state = [];
let setters = [];
let stateIndex = 0;

function createSetter (index) {
  return function (newState) {
    state[index] = newState;
    render ();
  }
}

function useState (initialState) {
  state[stateIndex] = state[stateIndex] ? state[stateIndex] : initialState;
  setters.push(createSetter(stateIndex));
  let value = state[stateIndex];
  let setter = setters[stateIndex];
  stateIndex++;
  return [value, setter];
}

function render () {
  stateIndex = 0;
  effectIndex = 0;
  ReactDOM.render(<App />, document.getElementById('root'));
}

// 上一次的依赖值
let prevDepsAry = [];
let effectIndex = 0;

function useEffect(callback, depsAry) {
  // 判断callback是不是函数
  if (Object.prototype.toString.call(callback) !== '[object Function]') throw new Error('useEffect函数的第一个参数必须是函数');
  // 判断depsAry有没有被传递
  if (typeof depsAry === 'undefined') {
    // 没有传递
    callback();
  } else {
    // 判断depsAry是不是数组
    if (Object.prototype.toString.call(depsAry) !== '[object Array]') throw new Error('useEffect函数的第二个参数必须是数组');
    // 获取上一次的状态值
    let prevDeps = prevDepsAry[effectIndex];
    // 将当前的依赖值和上一次的依赖值做对比 如果有变化 调用callback
    let hasChanged = prevDeps ? depsAry.every((dep, index) => dep === prevDeps[index]) === false : true;
    // 判断值是否有变化
    if (hasChanged) {
      callback();
    }
    // 同步依赖值
    prevDepsAry[effectIndex] = depsAry;
    effectIndex++;
  }
}

function useReducer (reducer, initialState) {
  const [state, setState] = useState(initialState);
  function dispatch (action) {
    const newState = reducer(state, action);
    setState(newState);
  }
  return [state, dispatch];
}

function App() {
  function reducer (state, action) {
    switch (action.type) {
      case 'increment':
        return state + 1;
      case 'decrement':
        return state - 1;
      default:
        return state;
    }
  }
  const [count, dispatch] = useReducer(reducer, 0);
  return <div>
    {count}
    <button onClick={() => dispatch({type: 'increment'})}>+1</button>
    <button onClick={() => dispatch({type: 'decrement'})}>-1</button>
  </div>;
}

export default App;


//  import React,{ useReducer } from 'react'

//  function reducer(state, action){
//    switch (action.type) {
//      case 'invrement':
//        return state + 1
//        break;
//        case 'decrement':
//         return state - 1
//         break;

//         default:
//         return state
//    }
//  }

//  function App(){
//    const [ count, dispatch ] = useReducer(reducer,0)
//    return <div>
//      <button onClick={()=> dispatch({type:'decrement'})}>-1</button>
//      <span>{count}</span>
//      <button onClick={()=> dispatch({type:'invrement'})}>+1</button>
//    </div>
//  }

//useMeo
// import React,{  useState, useMemo } from 'react'
// function App(){
//   const [count,setCount] = useState(0)
//   const [bool,setBool] = useState(true)
//   const result = useMemo(()=>{
//     return count * 2
//   },[count])
//   return <div>
//     <span>{count} {result}</span>
//     <span>{bool?'真':'假'}</span>
//     <button onClick={()=>setCount(count +1)}>+1</button>
//     <button onClick={()=>setBool(!bool)}>boolea</button>
//   </div>;

// }


// useErf
// import React, {useState,useEffect,useRef} from 'react'

// function App(){
//   const [count, setCount] = useState(0)
//   const timerId = useRef()
//   useEffect(()=>{
//     timerId.current =  setInterval(()=>{
//       setCount(count => count +1)
//     },1000)
//   },[])
//   const stopCount = ()=>{
//     console.log(timerId);
//     clearInterval(timerId.current)
//   }
//   return <div >
//     {count}
//     <button onClick={stopCount}>停止</button>
//   </div>
// }

//  export default App;